package com.dailywork.java8;

import com.common.comenum.DishType;
import com.common.model.Dish;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Java8Oper {
        public static void main(String[] args) {
                List<Dish> list = createList();
                java8Oper1(list);
        }

        private static List<Dish> createList() {
                List<Dish> list = Arrays.asList(new Dish("dish1", 10, DishType.COM.getValue(), Boolean.TRUE),
                                new Dish("dish2", 20, DishType.SELF.getValue(), Boolean.FALSE),
                                new Dish("dish1", 30, DishType.COM.getValue(), Boolean.TRUE),
                                new Dish("dish4", 25, DishType.COM.getValue(), Boolean.FALSE),
                                new Dish("dish5", 1, DishType.SPEC.getValue(), Boolean.TRUE));
                return list;
        }

        private static void java8Oper1(List<Dish> list) {
                Optional<Dish> maxDish = list.stream().max(Comparator.comparing(Dish::getSize));
                Optional<Dish> minDish = list.stream().min(Comparator.comparing(Dish::getSize));
                double average = list.stream().collect(Collectors.averagingInt(Dish::getSize));
                IntSummaryStatistics statistics = list.stream().collect(Collectors.summarizingInt(Dish::getSize));
        }

        private static void java8Oper2(List<Dish> list) {
                String str = list.stream().map(Dish::getName).collect(Collectors.joining(","));
                List<String> result = list.stream().map(Dish::getName).collect(Collectors.toCollection(ArrayList::new));
                Set<String> sets = list.stream().map(Dish::getName).collect(Collectors.toCollection(HashSet::new));
                Map<String, Dish> map = list.stream()
                                .collect(Collectors.toMap(Dish::getName, Function.identity(), (v1, v2) -> v2));
                List<Dish> list1 = list.stream().parallel().collect(Collectors.toCollection(ArrayList::new));
        }

        private static void java8Oper3(List<Dish> list) {
                Optional<Integer> sum = list.stream().map(Dish::getSize).reduce(Integer::sum);
                int summary = list.stream().mapToInt(Dish::getSize).sum();
                Optional<Dish> dish = list.stream().reduce((d1, d2) -> d1.getSize() > d2.getSize() ? d1 : d2);
                Map<String, List<Dish>> group = list.stream().collect(Collectors.groupingBy(Dish::getName));
                Map<String, Map<String, List<Dish>>> mapMap = list.stream()
                                .collect(Collectors.groupingBy(Dish::getType, Collectors.groupingBy(Dish::getName)));
                Map<String, Dish> map = list.stream().collect(Collectors.toMap(Dish::getType, Function.identity(),
                                BinaryOperator.maxBy(Comparator.comparing(Dish::getSize))));
                Map<String, Integer> map1 = list.stream()
                                .collect(Collectors.groupingBy(Dish::getType, Collectors.summingInt(Dish::getSize)));
                Map<String, Set<Integer>> map2 = list.stream().collect(Collectors.groupingBy(Dish::getType,
                                Collectors.mapping(Dish::getSize, Collectors.toCollection(HashSet::new))));
                // 分区
                Map<Boolean, List<Dish>> partition = list.stream()
                                .collect(Collectors.partitioningBy(Dish::isVegetarian));

                Map<Boolean, List<Integer>> partitionPrimes = IntStream.rangeClosed(2, 100).boxed()
                                .collect(Collectors.partitioningBy(Java8Oper::isPrime));
        }

        private static void java8Oper4(List<Dish> list) {
                Optional<Dish> dish = list.stream().findAny();
                int[] array = IntStream.range(1, 10).parallel().filter(val -> val % 2 == 0).toArray();
        }

        private static boolean isPrime(int candidate) {
                int candidateRoot = (int) Math.sqrt((double) candidate);
                return IntStream.rangeClosed(2, candidateRoot).noneMatch(i -> candidate % i == 0);
        }

        private static void java8Oper5() {
                Map<String, BigDecimal> map = new HashMap<>();
                map.put("one", new BigDecimal("0.08"));
                map.put("two", new BigDecimal("0.1"));
                map.put("three", new BigDecimal("0.2"));
                map.put("four", new BigDecimal("0.91"));
        }

        /**
         * map通过value排序
         *
         * @param map
         * @param <K>
         * @param <V>
         * @return
         */
        public <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
                Map<K, V> result = new LinkedHashMap<>();

                map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByValue().reversed())
                                .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
                return result;
        }

        /**
         * map通过key排序
         *
         * @param map
         * @param <K>
         * @param <V>
         * @return
         */
        public <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map) {
                Map<K, V> result = new LinkedHashMap<>();

                map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
                                .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
                return result;
        }
}
